﻿/*
SINACOR - BMF&Bovespa
Arquivo: ConsultaGeralOrdensNegocios.cs
Criado em: 07-abr-2010 15:53:18
Arquiteto Responsável: p-RAMelo
*/
using System;
using System.Collections.Generic;
using System.Text;
using Sinacor.Infra.Common;
using Sinacor.Infra.UI.Common;
using Sinacor.Infra.Common.Exceptions;
using System.Linq;
using Sinacor.Infra.UI.Authorization;


namespace Sinacor.UI.Bovespa.ManutencaoOrdens.Presenter
{
    /// <summary>
    /// Classe presenter para consulta geral de ordens e negócios
    /// </summary>
    public partial class ConsultaGeralOrdensNegocios : BasePresenter<IConsultaGeralOrdensNegocios>
    {

        #region Construtores

        /// <summary>
        /// Construtor
        /// </summary>
        public ConsultaGeralOrdensNegocios()
            : base(default(IConsultaGeralOrdensNegocios))
        {
        }

        /// <summary>
        /// Construtor
        /// </summary>
        /// <param name="view"></param>
        public ConsultaGeralOrdensNegocios(IConsultaGeralOrdensNegocios view)
            : base(view)
        {

            _communicationCalendario = new Sinacor.UI.Bovespa.ManutencaoOrdens.Communication.Calendario(this.Session);
            _communicationCasamento = new Sinacor.UI.Bovespa.ManutencaoOrdens.Communication.Casamento(this.Session);
            _communicationCliente = new Sinacor.UI.Bovespa.ManutencaoOrdens.Communication.Cliente(this.Session);
            _communicationControleMovimentoOrdens = new Sinacor.UI.Bovespa.ManutencaoOrdens.Communication.ControleMovimentoOrdens(this.Session);
            _communicationManutencaoOrdens = new Sinacor.UI.Bovespa.ManutencaoOrdens.Communication.ManutencaoOrdens(this.Session);
            _communicationNegocio = new Sinacor.UI.Bovespa.ManutencaoOrdens.Communication.Negocio(this.Session);
            _communicationOrdem = new Sinacor.UI.Bovespa.ManutencaoOrdens.Communication.Ordem(this.Session);
            _communicationPreBoleto = new Sinacor.UI.Bovespa.ManutencaoOrdens.Communication.PreBoleto(this.Session);
            _communicationTitulo = new Sinacor.UI.Bovespa.ManutencaoOrdens.Communication.Titulo(this.Session);
            _calendario = new ModelCollection<Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Calendario>();
            _informacoesMovimento = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.InformacoesMovimento();
            _negocios = new ModelCollection<Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Negocio>();
            _negociosDisponiveis = new ModelCollection<Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Negocio>();
            _negociosExecutados = new ModelCollection<Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Negocio>();
            _ordens = new ModelCollection<Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Ordem>();
            _permissoes = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Permissoes();
            _preBoletos = new ModelCollection<Sinacor.UI.Bovespa.ManutencaoOrdens.Model.PreBoleto>();
            _treeViewConsultaGeral = new ModelCollection<BaseModel>();

        }
        #endregion

        #region Atributos

        private ModelCollection<Model.Calendario> _calendario;
        private Communication.Calendario _communicationCalendario;
        private Communication.Casamento _communicationCasamento;
        private Communication.Cliente _communicationCliente;
        private Communication.ControleMovimentoOrdens _communicationControleMovimentoOrdens;
        private Communication.ManutencaoOrdens _communicationManutencaoOrdens;
        private Communication.Negocio _communicationNegocio;
        private Communication.Ordem _communicationOrdem;
        private Communication.PreBoleto _communicationPreBoleto;
        private Communication.Titulo _communicationTitulo;
        private Model.InformacoesMovimento _informacoesMovimento;
        private ModelCollection<Model.Negocio> _negocios;
        private ModelCollection<Model.Negocio> _negociosDisponiveis;
        private ModelCollection<Model.Negocio> _negociosExecutados;
        private ModelCollection<Model.Ordem> _ordens;
        private Model.Permissoes _permissoes;
        private ModelCollection<Model.PreBoleto> _preBoletos;
        private ModelCollection<BaseModel> _treeViewConsultaGeral;
        private Model.NoDataPregao _dataPregaoAtual;
        private Model.NoOrdem _ordemAtual;

        #endregion

        #region Propriedades

        /// <summary>
        /// Ordem selecionada
        /// </summary>
        public Model.NoOrdem OrdemAtual
        {
            get { return _ordemAtual; }
            set { _ordemAtual = value; }
        }

        /// <summary>
        /// Calendário de pregões
        /// </summary>
        public ModelCollection<Model.Calendario> Calendario
        {
            get { return _calendario; }
            set { _calendario = value; }
        }

        /// <summary>
        /// Informações sobre o movimento do módulo de ordens
        /// </summary>
        public Model.InformacoesMovimento InformacoesMovimento
        {
            get { return _informacoesMovimento; }
            set { _informacoesMovimento = value; }
        }

        /// <summary>
        /// Negócios
        /// </summary>
        public ModelCollection<Model.Negocio> Negocios
        {
            get { return _negocios; }
            set { _negocios = value; }
        }

        /// <summary>
        /// Binding com a data grid light de Negócios Não Casados
        /// </summary>
        public ModelCollection<Model.Negocio> NegociosDisponiveis
        {
            get { return _negociosDisponiveis; }
            set { _negociosDisponiveis = value; }
        }

        /// <summary>
        /// Binding com a data grid light de Execuções da Ordem
        /// </summary>
        public ModelCollection<Model.Negocio> NegociosExecutados
        {
            get { return _negociosExecutados; }
            set { _negociosExecutados = value; }
        }

        /// <summary>
        /// Ordens apresentadas na consulta geral
        /// </summary>
        public ModelCollection<Model.Ordem> Ordens
        {
            get { return _ordens; }
            set { _ordens = value; }
        }

        /// <summary>
        /// Permissões do operador logado
        /// </summary>
        public Model.Permissoes Permissoes
        {
            get { return _permissoes; }
            set { _permissoes = value; }
        }

        /// <summary>
        /// Binding com a data grid light de Pré-Boletos
        /// </summary>
        public ModelCollection<Model.PreBoleto> PreBoletos
        {
            get { return _preBoletos; }
            set { _preBoletos = value; }
        }

        /// <summary>
        /// Estrutura da treeview da consulta geral de ordens e negócios.
        /// </summary>
        public ModelCollection<BaseModel> TreeViewConsultaGeral
        {
            get { return _treeViewConsultaGeral; }
            set { _treeViewConsultaGeral = value; }
        }

        #endregion

        #region Métodos

        /// <summary>
        /// Realiza a alteração dos dados dos negócios enviadas como parâmetro de entrada
        /// </summary>
        /// <param name="nosNegocio"></param>
        /// <param name="destino"></param>
        public void AlterarNegocios(ModelCollection<Model.NoNegocio> nosNegocio, IHierarchicalItem destino)
        {
            var ret = (from v in nosNegocio
                       where (v.QuantidadeCasada == v.Quantidade) || (v.QuantidadeCasada > 0 && v.QuantidadeCasada < v.Quantidade)
                       select v).ToList<Model.NoNegocio>();

            if (ret != null)
            {
                if (View.ConfirmarAlteracaoNegocioCasado())
                {
                    if (ret[0].QuantidadeCasada > 0 && ret[0].QuantidadeCasada < ret[0].Quantidade)
                    {
                        if (View.ConfirmarAlteracaoNegocio())
                        {
                            foreach (Model.NoNegocio item in ret)
                            {
                                this.AlterarNegocio((Model.NoNegocio)item, destino);
                            }
                        }
                    }
                    else
                    {
                        foreach (Model.NoNegocio item in ret)
                        {
                            this.AlterarNegocio((Model.NoNegocio)item, destino);
                        }
                    }
                }
            }
            else
            {
                if (View.ConfirmarAlteracaoNegocio())
                {
                    foreach (Model.Negocio item in nosNegocio)
                    {
                        this.AlterarNegocio((Model.NoNegocio)item, destino);
                    }
                }
            }

        }

        /// <summary>
        /// Realiza a alteração dos dados das ordens enviadas como parâmetro de entrada
        /// </summary>
        /// <param name="nosOrdem"></param>
        /// <param name="destino"></param>
        public void AlterarOrdens(ModelCollection<Model.NoOrdem> nosOrdem, IHierarchicalItem destino)
        {
            if (View.ConfirmarAlteracaoOrdem())
            {
                foreach (Model.NoOrdem item in nosOrdem)
                {
                    this.AlterarOrdem((Model.NoOrdem)item, destino);
                }
            }

        }

        /// <summary>
        /// Cancela uma determinada ordem
        /// </summary>
        /// <param name="ordem"></param>
        public bool CancelarOrdem(Model.NoOrdem ordem)
        {
            try
            {
                if (View.ConfirmarCancelamentoOrdens())
                {
                    Model.Justificativa justificativa = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Justificativa();

                    justificativa.PendenteMensageria = true;
                    justificativa.NumeroOrdem = ordem.NumeroOrdem.Value;
                    justificativa.NumeroSubSequenciaOrdem = ordem.NumeroOrdemSubSequencia.Value;
                    justificativa.DataOrdem = ordem.DataOrdem;

                    Model.ChaveOrdem chaveOrdem = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.ChaveOrdem();

                    chaveOrdem.DataOrdem = ordem.DataOrdem;
                    chaveOrdem.NumeroOrdem = ordem.NumeroOrdem.Value;
                    chaveOrdem.NumeroOrdemSubSequencia = ordem.NumeroOrdemSubSequencia.Value;

                    _communicationManutencaoOrdens.CancelarOrdem(chaveOrdem, justificativa);

                    ordem.Situacao = Model.Enum.SituacaoOrdem.Cancelada;
                    return true;
                }

                return false;

            }
            catch (Exception ex)
            {
                base.HandleException(ex);
                return false;
            }
        }

        /// <summary>
        /// Carrega as ordens e negócios de uma determinada data de pregão
        /// </summary>
        /// <param name="noDataPregao"></param>
        public void CarregarDataPregao(Model.NoDataPregao noDataPregao)
        {

            _dataPregaoAtual = noDataPregao;

            Ordens = this.ConsultarOrdens(new Model.Parameter.FiltroOrdem() { DataPregao = noDataPregao.DataPregao });

            Negocios = this.ConsultarNegocios(new Model.Parameter.FiltroNegocio() { DataPregao = noDataPregao.DataPregao });

            this.CarregarClientes(ref noDataPregao);

            View.AtualizarTreeView();

        }

        /// <summary>
        /// Realiza o casamento dos negócios para a ordem
        /// </summary>
        /// <param name="negocios"></param>
        public bool CasarNegocios(Model.ChaveOrdem ordem, ModelCollection<Model.Negocio> negocios)
        {
            try
            {
                if (View.ConfirmarCasamento())
                {
                    _communicationCasamento.CasarNegocios(ordem, negocios);
                    return true;
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
            return false;
        }

        /// <summary>
        /// Realiza o casamento dos pré-boletos selecionados
        /// </summary>
        /// <param name="ordem"></param>
        public bool CasarPreBoletos(Model.NoOrdem ordem)
        {
            if (View.ConfirmarCasamentoPreBoletos())
            {
                try
                {
                    Model.Parameter.FiltroPreBoleto param = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Parameter.FiltroPreBoleto();

                    param.DataPregao = _dataPregaoAtual.DataPregao;
                    param.Ordem = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.ChaveOrdem() { DataOrdem = ordem.DataOrdem, NumeroOrdem = ordem.NumeroOrdem.Value, NumeroOrdemSubSequencia = ordem.NumeroOrdemSubSequencia.Value };

                    _communicationCasamento.CasarPreBoletos(param);
                    return true;

                }
                catch (Exception ex)
                {
                    base.HandleException(ex);
                    return false;
                }
            }
            return false;
        }

        /// <summary>
        /// Consulta os negócios disponíveis para o casamento da ordem passada como
        /// parâmetro de entrada
        /// </summary>
        /// <param name="ordem"></param>
        public void ConsultarNegociosDisponiveis(Model.ChaveOrdem ordem)
        {
            try
            {
                NegociosDisponiveis = _communicationNegocio.ConsultarNegociosDisponiveis(ordem);
                View.AtualizarNegociosDisponiveis();
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }

        /// <summary>
        /// Consulta os negócios executados (casados) para a ordem passada como parâmetro
        /// de entrada e atualiza a interface
        /// </summary>
        /// <param name="ordem"></param>
        public void ConsultarNegociosCasados(Model.ChaveOrdem ordem)
        {
            NegociosExecutados = this.ConsultarNegociosExecutados(ordem);
            View.AtualizarNegociosExecutados();
        }

        /// <summary>
        /// Consulta os pré-boletos de uma determinada ordem
        /// </summary>
        /// <param name="ordem"></param>
        public void ConsultarPreBoletos(Model.ChaveOrdem ordem)
        {
            try
            {
                Model.Parameter.FiltroPreBoleto filtro = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Parameter.FiltroPreBoleto();

                filtro.DataPregao = _dataPregaoAtual.DataPregao;

                filtro.Ordem = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.ChaveOrdem()
                {
                    DataOrdem = ordem.DataOrdem,
                    NumeroOrdem = ordem.NumeroOrdem,
                    NumeroOrdemSubSequencia = ordem.NumeroOrdemSubSequencia
                };

                PreBoletos = _communicationPreBoleto.ConsultarPreBoletos(filtro);

                View.AtualizarPreBoletos();

            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }

        /// <summary>
        /// Descasa os negócios selecionados
        /// </summary>
        /// <param name="negocios"></param>
        public void DescasarNegocios(ModelCollection<Model.Negocio> negocios, bool solicitaConfirmacao)
        {
            try
            {
                if (solicitaConfirmacao)
                {
                    if (View.ConfirmarDescasamento())
                        _communicationCasamento.DescasarNegocios(negocios);
                }
                else
                    _communicationCasamento.DescasarNegocios(negocios);

            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }

        }

        /// <summary>
        /// Exclui o negócio informado como parâmetro de entrada
        /// </summary>
        /// <param name="negocio"></param>
        public bool ExcluirNegocio(Model.NoNegocio negocio)
        {
            try
            {
                if (View.ConfirmarExclusaoNegocio())
                {
                    Model.Parameter.FiltroNegocioChave filtro = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Parameter.FiltroNegocioChave();

                    filtro.Bolsa = negocio.Bolsa;
                    filtro.DataPregao = negocio.DataPregao;
                    filtro.Ativo = negocio.Codigo;
                    filtro.NaturezaOperacao = negocio.NaturezaOperacao.Value;
                    filtro.Numero = negocio.Numero;

                    _communicationNegocio.ExcluirNegocioControleOrdens(filtro);

                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
                return false;
            }

        }

        /// <summary>
        /// Realiza a exclusão dos pré-boletos selecionados
        /// </summary>
        /// <param name="preBoletos"></param>
        public bool ExcluirPreBoletos(ModelCollection<Model.PreBoleto> preBoletos)
        {
            try
            {
                if (View.ConfirmarExclusaoPreBoletos())
                {
                    foreach (Model.PreBoleto item in preBoletos)
                    {
                        _communicationPreBoleto.ExcluirPreBoleto(new Model.Parameter.FiltroPreBoletoChave() { Numero = item.Numero.Value });
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
                return false;
            }
            return false;
        }

        /// <summary>
        /// Inicializa a tela consulta geral de ordens e negócios
        /// </summary>
        public void Inicializar()
        {
            this.ObterPermissoes();
            InformacoesMovimento = this.ObterInformacoesMovimento();
            Calendario = this.ConsultarCalendario();
            this.CarregarCalendarioPregoes();
            this.CarregarDataPregao(_treeViewConsultaGeral[0] as Model.NoDataPregao);

        }

        /// <summary>
        /// Valida o movimento drag and drop realizado na treeview
        /// </summary>
        /// <param name="origem"></param>
        /// <param name="destino"></param>
        public bool ValidarMovimento(IHierarchicalItem origem, IHierarchicalItem destino)
        {
            bool retorno = false;

            if (this.ValidarOrigem(origem))
            {
                if (this.ValidarDestino(destino))
                {
                    if (origem is Model.NoOrdem)
                    {
                        if (this.ValidarMovimentoNoOrdem((Model.NoOrdem)origem, destino))
                            retorno = true;
                    }
                    else
                    {
                        if (ValidarMovimentoNoNegocio((Model.NoNegocio)origem, destino))
                            retorno = true;
                    }
                }
            }
            else
                retorno = false;

            return retorno;
        }

        /// <summary>
        /// Análisa o estado do casamento de um negócio e apresenta a cor relacionada
        /// </summary>
        /// <param name="negocio"></param>
        public void VerificarEstadoNegocio(Model.Negocio negocio)
        {

            if (negocio.QuantidadeCasada == 0)
                View.ApresentarNegocioNaoCasado();
            else if (negocio.QuantidadeCasada > 0 && negocio.QuantidadeCasada < negocio.Quantidade)
            {
                View.ApresentarNegocioParcialmenteCasado();
            }
            else
                View.ApresentarPreBoletoCasado();


        }

        /// <summary>
        /// Análisa o estado do casamento de um pré-boleto e apresenta a cor relacionada
        /// </summary>
        /// <param name="preBoleto"></param>
        public void VerificarEstadoPreBoleto(Model.PreBoleto preBoleto)
        {
            if (preBoleto.QuantidadeCasada == 0)
            {
                View.ApresentarPreBoletoNaoCasado();
            }
            else if (preBoleto.QuantidadeCasada == preBoleto.Quantidade)
            {
                View.ApresentarPreBoletoCasado();
            }
            else if (preBoleto.QuantidadeCasada > 0 && preBoleto.QuantidadeCasada < preBoleto.Quantidade)
            {
                View.ApresentarPreBoletoParcialmenteCasado();
            }
        }

        /// <summary>
        /// Analisa o estado do casamento de uma ordem e apresenta a cor relacionada
        /// </summary>
        /// <param name="preBoleto"></param>
        public void VerificarEstadoOrdem(Model.Ordem ordem)
        {
            if (ordem.QuantidadeExecutada == 0 && ordem.Situacao == Model.Enum.SituacaoOrdem.Cancelada)
            {
                ordem.SituacaoCasamento = Model.Enum.SituacaoCasamento.NaoCasada;
                View.ApresentarNegocioCancelado();
            }
            else if (ordem.QuantidadeExecutada == ordem.Quantidade)
            {
                ordem.SituacaoCasamento = Model.Enum.SituacaoCasamento.Casada;
                View.ApresentarPreBoletoCasado();
            }
            else if (ordem.QuantidadeExecutada > 0 && ordem.QuantidadeExecutada < ordem.Quantidade)
            {
                ordem.SituacaoCasamento = Model.Enum.SituacaoCasamento.ParcialmenteCasada;
                View.ApresentarPreBoletoParcialmenteCasado();
            }
            else if (ordem.QuantidadeExecutada == 0)
            {
                ordem.SituacaoCasamento = Model.Enum.SituacaoCasamento.NaoCasada;
                View.ApresentarPreBoletoNaoCasado();
            }

        }

        #endregion

        #region Métodos privados

        /// <summary>
        /// Altera os dados de uma ordem conforme seu novo destino
        /// </summary>
        /// <param name="noOrdem"></param>
        /// <param name="destino"></param>
        private void AlterarOrdem(Model.NoOrdem noOrdem, IHierarchicalItem destino)
        {
            bool _descasaOrdem = false;
            bool _alteraOrdem = true;

            if (destino is Model.NoNaturezaOperacao)
                noOrdem.NaturezaOperacao = ((Model.NoNaturezaOperacao)destino).Natureza;
            else if (destino is Model.NoDiscricionaria)
            {
                noOrdem.NaturezaOperacao = ((Model.NoNaturezaOperacao)destino.Parent.Parent).Natureza;
                noOrdem.Discricionaria = ((Model.NoDiscricionaria)destino).Discricionaria;
            }
            else if (destino is Model.NoSituacaoCasamento)
            {
                if (noOrdem.Parent.Parent == destino.Parent && noOrdem.Parent.Parent.Parent.Parent == destino.Parent.Parent.Parent)
                {
                    if (((Model.NoSituacaoCasamento)destino).Situacao == Model.Enum.SituacaoCasamento.NaoCasada)
                    {
                        _descasaOrdem = true;
                        _alteraOrdem = true;
                    }
                    else
                        _alteraOrdem = false;
                }
            }
            else if (noOrdem.NaturezaOperacao == ((Model.NoNaturezaOperacao)destino).Natureza)
            {
                noOrdem.Discricionaria = ((Model.NoDiscricionaria)destino).Discricionaria;

                if (((Model.NoSituacaoCasamento)destino).Situacao == Model.Enum.SituacaoCasamento.NaoCasada)
                    _descasaOrdem = true;
            }


            if (_descasaOrdem)
            {
                Model.ChaveOrdem param = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.ChaveOrdem();
                param.DataOrdem = noOrdem.DataOrdem;
                param.NumeroOrdem = noOrdem.NumeroOrdem.Value;
                param.NumeroOrdemSubSequencia = noOrdem.NumeroOrdemSubSequencia.Value;

                ModelCollection<Model.Negocio> retornoNegExec = this.ConsultarNegociosExecutados(param);

                this.DescasarNegocios(retornoNegExec, false);
            }

            if (_alteraOrdem)
            {
                Model.Justificativa justificativa = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Justificativa();
                justificativa.PendenteMensageria = true;
                justificativa.NumeroOrdem = noOrdem.NumeroOrdem.Value;
                justificativa.NumeroSubSequenciaOrdem = noOrdem.NumeroOrdemSubSequencia.Value;
                justificativa.DataOrdem = noOrdem.DataOrdem;

                try
                {
                    if (destino is Model.NoDiscricionaria)
                    {
                        if (noOrdem.NaturezaOperacao == Model.Enum.NaturezaOperacao.Compra
                            && ((Model.NoNaturezaOperacao)destino.Parent.Parent).Natureza == Model.Enum.NaturezaOperacao.Venda)
                            noOrdem.NaturezaOperacao = Model.Enum.NaturezaOperacao.Venda;

                        if (noOrdem.NaturezaOperacao == Model.Enum.NaturezaOperacao.Venda
                            && ((Model.NoNaturezaOperacao)destino.Parent.Parent).Natureza == Model.Enum.NaturezaOperacao.Compra)
                            noOrdem.NaturezaOperacao = Model.Enum.NaturezaOperacao.Compra;

                        if (noOrdem.Discricionaria.Value && !((Model.NoDiscricionaria)destino).Discricionaria)
                            noOrdem.Discricionaria = false;

                        if (!noOrdem.Discricionaria.Value && ((Model.NoDiscricionaria)destino).Discricionaria)
                            noOrdem.Discricionaria = true;                      
                    }

                    else
                    {
                        if (noOrdem.NaturezaOperacao == Model.Enum.NaturezaOperacao.Compra
                            && ((Model.NoNaturezaOperacao)destino.Parent.Parent.Parent).Natureza == Model.Enum.NaturezaOperacao.Venda)
                        {
                            noOrdem.NaturezaOperacao = Model.Enum.NaturezaOperacao.Venda;
                        }

                        if (noOrdem.NaturezaOperacao == Model.Enum.NaturezaOperacao.Venda && ((Model.NoNaturezaOperacao)destino.Parent.Parent.Parent).Natureza == Model.Enum.NaturezaOperacao.Compra)
                        {
                            noOrdem.NaturezaOperacao = Model.Enum.NaturezaOperacao.Compra;
                        }

                        if (noOrdem.Discricionaria.Value && !((Model.NoDiscricionaria)destino.Parent).Discricionaria)
                        {
                            noOrdem.Discricionaria = false;
                        }

                        if (!noOrdem.Discricionaria.Value && ((Model.NoDiscricionaria)destino.Parent).Discricionaria)
                        {
                            noOrdem.Discricionaria = true;
                        }

                        if ((noOrdem.SituacaoCasamento == Model.Enum.SituacaoCasamento.Casada || noOrdem.SituacaoCasamento == Model.Enum.SituacaoCasamento.ParcialmenteCasada) && (((Model.NoSituacaoCasamento)destino).Situacao == Model.Enum.SituacaoCasamento.NaoCasada))
                        {
                            noOrdem.SituacaoCasamento = Model.Enum.SituacaoCasamento.NaoCasada;
                            noOrdem.QuantidadeExecutada = 0;
                        }
                    }

                    _communicationManutencaoOrdens.AlterarOrdem(noOrdem, justificativa);
                    this.TransferirNo(noOrdem, destino);

                }
                catch (Exception ex)
                {
                    base.HandleException(ex);
                }
            }

        }

        /// <summary>
        /// Altera os dados de um negócio conforme seu novo destino
        /// </summary>
        /// <param name="noNegocio"></param>
        /// <param name="destino"></param>
        private void AlterarNegocio(Model.NoNegocio noNegocio, IHierarchicalItem destino)
        {
            bool _alteraNegocio = true;
            bool _erroNegocio = false;

            if (destino is Model.NoNaturezaOperacao)
            {
                noNegocio.NaturezaOperacao = ((Model.NoNaturezaOperacao)destino).Natureza;
            }
            else if (destino is Model.NoSituacaoCasamento)
            {
                if (noNegocio.Parent.Parent.Parent == destino.Parent.Parent)
                    _alteraNegocio = false;


                if (((Model.NoSituacaoCasamento)destino).Situacao == Model.Enum.SituacaoCasamento.NaoCasada)
                {
                    ModelCollection<Model.Ordem> ordens = this.ConsultarOrdensExecutadas(noNegocio);

                    ModelCollection<Model.Negocio> negocios = new ModelCollection<Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Negocio>();

                    _alteraNegocio = true;

                    foreach (Model.Ordem item in ordens)
                    {
                        Model.Negocio negocio = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Negocio();
                        negocio.Ordem = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.ChaveOrdem();

                        negocio.Ordem.NumeroOrdem = item.NumeroOrdem.Value;
                        negocio.Ordem.NumeroOrdemSubSequencia = item.NumeroOrdemSubSequencia.Value;
                        negocio.Ordem.DataOrdem = item.DataOrdem;
                        negocio.DataPregao = noNegocio.DataPregao;


                        negocio.Codigo = noNegocio.Codigo;
                        negocio.Numero = noNegocio.Numero;
                        negocio.NaturezaOperacao = noNegocio.NaturezaOperacao.Value;
                        negocio.Bolsa = noNegocio.Bolsa;

                        negocios.Add(negocio);
                    }

                    try
                    {
                        _communicationCasamento.DescasarNegocios(negocios);
                    }
                    catch (Exception ex)
                    {
                        base.HandleException(ex);
                        _erroNegocio = true;
                    }
                }

            }

            if (_alteraNegocio && !_erroNegocio)
            {
                try
                {
                    _communicationNegocio.AlterarNegocioControleOrdens(noNegocio);

                }
                catch (Exception ex)
                {
                    base.HandleException(ex);
                }
            }

            if (!_erroNegocio)
                this.TransferirNo(noNegocio, destino);
        }

        /// <summary>
        /// Carrega o calendário de pregões e o nó de descarte na estrutura da treeview
        /// </summary>
        private void CarregarCalendarioPregoes()
        {

            var datas = (from v in Calendario
                         orderby v.DataPregao descending
                         select v);

            foreach (Model.Calendario item in datas)
            {
                Model.NoDataPregao noDataPregao = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoDataPregao((Model.Calendario)item);
                _treeViewConsultaGeral.Add(noDataPregao);
            }

            _treeViewConsultaGeral.Add(new Model.NoDescarte(null) { });

        }

        /// <summary>
        /// Carrega o nível de clientes na data de pregão
        /// </summary>
        /// <param name="noDataPregao"></param>
        private void CarregarClientes(ref Model.NoDataPregao noDataPregao)
        {
            if (noDataPregao.Children.Count > 0)
                noDataPregao.Children.Clear();

            List<int> codigosClientes = new List<int>();

            if (_ordens != null
                && _negocios != null)
            {
                //Resgatar clientes de Ordens
                var codigosClientesOrdens = (from v in Ordens
                                             where v.CodigoCliente.Value > 0
                                             select v.CodigoCliente.Value).Distinct().ToList();


                //Resgatar clientes de Negocios
                var codigosClientesNegocios = (from v in Negocios
                                               select v.CodigoCliente.Value).Distinct().ToList();


                // Resgatar clientes das duas listas
                codigosClientes = (from v in codigosClientesOrdens
                                   select v).Union(from p in codigosClientesNegocios
                                                   select p).Distinct().ToList<int>();
            }
            else if (_ordens != null)
            {
                codigosClientes = (from v in Ordens
                                   where v.CodigoCliente.Value > 0
                                   select v.CodigoCliente.Value).Distinct().ToList();

            }
            else if (_negocios != null)
            {
                codigosClientes = (from v in Negocios
                                   select v.CodigoCliente.Value).Distinct().ToList();
            }

            //Looping na Lista codigosClientes
            foreach (int item in codigosClientes)
            {
                Model.Cliente cliente = this.ObterCliente(new Model.Parameter.FiltroCliente() { CodigoCliente = item });

                if (cliente != null)
                {
                    Model.NoCliente noCliente = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoCliente(noDataPregao, cliente);

                    this.CarregarTitulos(ref noCliente);

                    noDataPregao.Children.Add(noCliente);
                }

            }
        }

        /// <summary>
        /// Carrega o nível de natureza das operação informada como parâmetro de entrada
        /// </summary>
        /// <param name="noTitulo"></param>
        /// <param name="naturezaOperacao"></param>
        private void CarregarNaturezaOperacao(ref Model.NoTitulo noTitulo, Model.Enum.NaturezaOperacao naturezaOperacao)
        {
            Model.NoNaturezaOperacao noNatureza = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoNaturezaOperacao(noTitulo, naturezaOperacao);

            this.CarregarOrdens(ref noNatureza);

            this.CarregarNegocios(ref noNatureza);

            noTitulo.Children.Add(noNatureza);
        }

        /// <summary>
        /// Carrega a estrutura de negócios na treeview
        /// </summary>
        /// <param name="noNaturezaOperacao"></param>
        private void CarregarNegocios(ref Model.NoNaturezaOperacao noNaturezaOperacao)
        {
            Model.NoTipoObjetoConsulta noTipoObjetoConsultaNegocio;

            Model.NoSituacaoCasamento noCasadasParcial;

            Model.NoSituacaoCasamento noNaoCasadas;

            noTipoObjetoConsultaNegocio = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoTipoObjetoConsulta(noNaturezaOperacao, Model.Enum.TipoObjetoConsulta.Negocio);

            noCasadasParcial = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoSituacaoCasamento(noTipoObjetoConsultaNegocio, Model.Enum.SituacaoCasamento.Casada);

            noNaoCasadas = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoSituacaoCasamento(noTipoObjetoConsultaNegocio, Model.Enum.SituacaoCasamento.NaoCasada);

            noTipoObjetoConsultaNegocio.Children.Add(noCasadasParcial);
            noTipoObjetoConsultaNegocio.Children.Add(noNaoCasadas);

            //Casadas
            Model.Parameter.FiltroOrdem filtro = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Parameter.FiltroOrdem();

            filtro.Casadas = true;
            filtro.NaoCasadas = false;
            filtro.CasadasParcialmente = false;
            filtro.Ativo = noNaturezaOperacao.Parent.Codigo;
            filtro.NaturezaOperacao = noNaturezaOperacao.Natureza;
            filtro.Cliente = noNaturezaOperacao.Parent.Parent.Codigo;

            ModelCollection<Model.Negocio> retorno = this.ConsultarNosNegocios(filtro);

            foreach (Model.Negocio item in retorno)
            {
                Model.NoNegocio noNegocio = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoNegocio(noCasadasParcial, item);
                noCasadasParcial.Children.Add(noNegocio);
            }


            //Casadas Parcial
            Model.Parameter.FiltroOrdem filtroCasadasParcial = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Parameter.FiltroOrdem();

            filtroCasadasParcial.Casadas = false;
            filtroCasadasParcial.NaoCasadas = false;
            filtroCasadasParcial.CasadasParcialmente = true;
            filtroCasadasParcial.Ativo = noNaturezaOperacao.Parent.Codigo;
            filtroCasadasParcial.NaturezaOperacao = noNaturezaOperacao.Natureza;
            filtroCasadasParcial.Cliente = noNaturezaOperacao.Parent.Parent.Codigo;


            ModelCollection<Model.Negocio> retornoNosNeg = this.ConsultarNosNegocios(filtroCasadasParcial);

            foreach (Model.Negocio item in retornoNosNeg)
            {
                Model.NoNegocio no = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoNegocio(noCasadasParcial, item);
                noCasadasParcial.Children.Add(no);
            }


            //Não Casadas
            Model.Parameter.FiltroOrdem filtroNaoCasadas = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Parameter.FiltroOrdem();

            filtroNaoCasadas.Casadas = false;
            filtroNaoCasadas.NaoCasadas = true;
            filtroNaoCasadas.CasadasParcialmente = false;
            filtroNaoCasadas.Ativo = noNaturezaOperacao.Parent.Codigo;
            filtroNaoCasadas.NaturezaOperacao = noNaturezaOperacao.Natureza;
            filtroNaoCasadas.Cliente = noNaturezaOperacao.Parent.Parent.Codigo;

            ModelCollection<Model.Negocio> negocios = this.ConsultarNosNegocios(filtroNaoCasadas);

            foreach (Model.Negocio item in negocios)
            {
                Model.NoNegocio noNCasada = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoNegocio(noNaoCasadas, item);
                noNaoCasadas.Children.Add(noNCasada);
            }

            noNaturezaOperacao.Children.Add(noTipoObjetoConsultaNegocio);

        }

        /// <summary>
        /// Carrega a estrutura de ordens na treeview
        /// </summary>
        /// <param name="noNaturezaOperacao"></param>
        private void CarregarOrdens(ref Model.NoNaturezaOperacao noNaturezaOperacao)
        {

            Model.NoTipoObjetoConsulta tipoObj = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoTipoObjetoConsulta(noNaturezaOperacao, Model.Enum.TipoObjetoConsulta.Ordem);

            this.CarregarOrdensDiscricionarias(ref tipoObj, true);

            this.CarregarOrdensDiscricionarias(ref tipoObj, false);

            noNaturezaOperacao.Children.Add(tipoObj);

        }

        /// <summary>
        /// Carrega as ordens discricionárias e não discricionárias
        /// </summary>
        /// <param name="noTipoObjetoConsultaOrdem"></param>
        /// <param name="discricionaria"></param>
        private void CarregarOrdensDiscricionarias(ref Model.NoTipoObjetoConsulta noTipoObjetoConsultaOrdem, bool discricionaria)
        {

            Model.NoDiscricionaria noDiscricionaria;
            Model.NoSituacaoCasamento noCasadasParcial;
            Model.NoSituacaoCasamento noNaoCasadas;

            noDiscricionaria = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoDiscricionaria(noTipoObjetoConsultaOrdem, discricionaria);

            noCasadasParcial = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoSituacaoCasamento(noDiscricionaria, Model.Enum.SituacaoCasamento.Casada);

            noNaoCasadas = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoSituacaoCasamento(noDiscricionaria, Model.Enum.SituacaoCasamento.NaoCasada);

            noDiscricionaria.Children.Add(noCasadasParcial);
            noDiscricionaria.Children.Add(noNaoCasadas);

            //Casadas Parcial
            Model.Parameter.FiltroOrdem filtro = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Parameter.FiltroOrdem();

            filtro.Discricionaria = discricionaria;
            filtro.Casadas = true;
            filtro.NaoCasadas = false;
            filtro.CasadasParcialmente = false;
            filtro.Ativo = noTipoObjetoConsultaOrdem.Parent.Parent.Codigo;
            filtro.NaturezaOperacao = noTipoObjetoConsultaOrdem.Parent.Natureza;
            filtro.Cliente = noTipoObjetoConsultaOrdem.Parent.Parent.Parent.Codigo;

            ModelCollection<Model.Ordem> retorno = this.ConsultarNosOrdens(filtro);

            foreach (Model.Ordem item in retorno)
            {
                Model.NoOrdem no = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoOrdem(noCasadasParcial, item);
                noCasadasParcial.Children.Add(no);
            }

            Model.Parameter.FiltroOrdem filtroCasadasParcial = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Parameter.FiltroOrdem();

            filtroCasadasParcial.Discricionaria = discricionaria;
            filtroCasadasParcial.Casadas = false;
            filtroCasadasParcial.NaoCasadas = false;
            filtroCasadasParcial.CasadasParcialmente = true;
            filtroCasadasParcial.Ativo = noTipoObjetoConsultaOrdem.Parent.Parent.Codigo;
            filtroCasadasParcial.NaturezaOperacao = noTipoObjetoConsultaOrdem.Parent.Natureza;
            filtroCasadasParcial.Cliente = noTipoObjetoConsultaOrdem.Parent.Parent.Parent.Codigo;

            ModelCollection<Model.Ordem> ordensNCasadas = this.ConsultarNosOrdens(filtroCasadasParcial);

            foreach (Model.Ordem item in ordensNCasadas)
            {
                Model.NoOrdem no = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoOrdem(noCasadasParcial, item);
                noCasadasParcial.Children.Add(no);
            }


            Model.Parameter.FiltroOrdem filtroNCasada = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Parameter.FiltroOrdem();

            filtroNCasada.Discricionaria = discricionaria;
            filtroNCasada.Casadas = false;
            filtroNCasada.NaoCasadas = true;
            filtroNCasada.CasadasParcialmente = false;
            filtroNCasada.Ativo = noTipoObjetoConsultaOrdem.Parent.Parent.Codigo;
            filtroNCasada.NaturezaOperacao = noTipoObjetoConsultaOrdem.Parent.Natureza;
            filtroNCasada.Cliente = noTipoObjetoConsultaOrdem.Parent.Parent.Parent.Codigo;

            ModelCollection<Model.Ordem> retornoNCasa = this.ConsultarNosOrdens(filtroNCasada);

            foreach (Model.Ordem item in retornoNCasa)
            {
                Model.NoOrdem no = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoOrdem(noNaoCasadas, item);
                noNaoCasadas.Children.Add(no);
            }

            noTipoObjetoConsultaOrdem.Children.Add(noDiscricionaria);

        }

        /// <summary>
        /// Carrega o nível de ativos para um determinado cliente
        /// </summary>
        /// <param name="noCliente"></param>
        private void CarregarTitulos(ref Model.NoCliente noCliente)
        {
            List<String> codigosAtivos = new List<string>();
            int codigoCliente = noCliente.Codigo.Value;

            if (_ordens != null
                && _negocios != null)
            {
                //Resgatar titulos de Ordens
                var codigosAtivosOrdens = (from v in Ordens
                                           where v.CodigoCliente == codigoCliente && v.Ativo != null
                                           select v.Ativo).Distinct().ToList();

                //Resgatar titulos de Negocios
                var codigosAtivosNegocios = (from v in Negocios
                                             where v.CodigoCliente == codigoCliente && v.Codigo != null
                                             select v.Codigo).Distinct().ToList();


                // Resgatar titulos das listas codigosAtivosOrdens e codigosAtivosNegocios
                codigosAtivos = (from v in codigosAtivosOrdens
                                 select v).Union(from p in codigosAtivosNegocios
                                                 select p).Distinct().ToList();
            }
            else if (_ordens != null)
            {
                codigosAtivos = (from v in Ordens
                                           where v.CodigoCliente == codigoCliente && v.Ativo != null
                                           select v.Ativo).Distinct().ToList();
            }
            else if (_negocios != null)
            {
                codigosAtivos = (from v in Negocios
                                 where v.CodigoCliente == codigoCliente && v.Codigo != null
                                 select v.Codigo).Distinct().ToList();
            }

            foreach (string item in codigosAtivos)
            {
                Model.Parameter.FiltroTitulo filtroTitulo = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Parameter.FiltroTitulo();

                filtroTitulo.CodigoNegocio = item;
                filtroTitulo.DataPregao = noCliente.Parent.DataPregao;

                Model.Titulo titulo = this.ObterTitulo(filtroTitulo);

                Model.NoTitulo noTitulo = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoTitulo(noCliente, titulo);

                this.CarregarNaturezaOperacao(ref noTitulo, Model.Enum.NaturezaOperacao.Compra);
                this.CarregarNaturezaOperacao(ref noTitulo, Model.Enum.NaturezaOperacao.Venda);

                noCliente.Children.Add(noTitulo);
            }
        }

        /// <summary>
        /// Consulta o calendário de pregões
        /// </summary>
        private ModelCollection<Model.Calendario> ConsultarCalendario()
        {
            ModelCollection<Model.Calendario> retorno = null;

            try
            {
                retorno = _communicationCalendario.ConsultarCalendario();
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
            return retorno;
        }

        /// <summary>
        /// Consulta negócios à partir dos filtros informados
        /// </summary>
        /// <param name="parameter"></param>
        private ModelCollection<Model.Negocio> ConsultarNegocios(Model.Parameter.FiltroNegocio parameter)
        {
            ModelCollection<Model.Negocio> retorno = null;

            try
            {
                retorno = _communicationNegocio.ConsultarNegocios(parameter);
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }

            return retorno;

        }

        /// <summary>
        /// Valida se o usuário possui permissão para o movimento do nó ordem
        /// </summary>
        /// <param name="origem"></param>
        /// <param name="destino"></param>
        private bool ValidarPermissaoOrdem(Model.NoOrdem origem, IHierarchicalItem destino)
        {
            bool retorno = false;

            if (destino is Model.NoDescarte)
            {
                if (Permissoes.PermiteCancelar == true)
                    retorno = true;
                else
                    retorno = false;
            }
            else
            {
                if (destino is Model.NoNaturezaOperacao || destino is Model.NoDiscricionaria)
                {
                    if (Permissoes.PermiteAlterar == true)
                        retorno = true;
                    else
                        retorno = false;
                }
                else
                {
                    if (destino is Model.NoSituacaoCasamento)
                    {
                        if (Permissoes.PermiteAlterar == true || Permissoes.PermiteCancelar == true || Permissoes.PermiteIncluir == true)
                            retorno = true;
                        else
                            retorno = false;
                    }
                }
            }

            return retorno;

        }

        /// <summary>
        /// Valida a movimentação de um negócio a um destino
        /// </summary>
        /// <param name="origem"></param>
        /// <param name="destino"></param>
        private bool ValidarMovimentoNoNegocio(Model.NoNegocio origem, IHierarchicalItem destino)
        {
            bool retorno = false;

            if (this.ValidarPermissaoNegocio(origem, destino))
            {
                if (destino is Model.NoSituacaoCasamento)
                {
                    if (destino != origem.Parent)
                    {
                        if (destino.Parent.Parent.Parent.Parent == origem.Parent.Parent.Parent.Parent.Parent)
                        {
                            if (destino.Parent.Parent.Parent == origem.Parent.Parent.Parent.Parent)
                            {
                                if ((((Model.NoTipoObjetoConsulta)destino.Parent).TipoObjeto == Model.Enum.TipoObjetoConsulta.Negocio) && ((Model.NoSituacaoCasamento)destino).Situacao == Model.Enum.SituacaoCasamento.NaoCasada)
                                {
                                    retorno = true;
                                }
                            }
                        }
                    }
                }
                else if (destino is Model.NoNaturezaOperacao)
                {
                    if (destino != origem.Parent.Parent.Parent)
                    {
                        if (destino.Parent.Parent == origem.Parent.Parent.Parent.Parent.Parent)
                        {
                            if (destino.Parent == origem.Parent.Parent.Parent.Parent)
                            {
                                retorno = true;
                            }
                        }
                    }
                }
                else if (destino is Model.NoDescarte)
                    retorno = true;
            }
            else
                retorno = false;

            return retorno;
        }

        /// <summary>
        /// Valida a movimentação de uma ordem a um destino
        /// </summary>
        /// <param name="origem"></param>
        /// <param name="destino"></param>
        private bool ValidarMovimentoNoOrdem(Model.NoOrdem origem, IHierarchicalItem destino)
        {
            bool retorno = false;

            if (this.ValidarPermissaoOrdem(origem, destino))
            {
                if (destino is Model.NoSituacaoCasamento)
                {
                    if (destino != origem.Parent)
                    {
                        if (destino.Parent.Parent.Parent.Parent.Parent == origem.Parent.Parent.Parent.Parent.Parent.Parent)
                        {
                            if (destino.Parent.Parent.Parent.Parent == origem.Parent.Parent.Parent.Parent.Parent)
                            {
                                if (destino.Parent is Model.NoDiscricionaria && ((Model.NoTipoObjetoConsulta)destino.Parent.Parent).TipoObjeto == Model.Enum.TipoObjetoConsulta.Ordem)
                                {
                                    if (((Model.NoSituacaoCasamento)destino).Situacao == Model.Enum.SituacaoCasamento.NaoCasada)
                                    {
                                        retorno = true;
                                    }

                                }
                            }
                        }
                    }
                }
                else if (destino is Model.NoDiscricionaria)
                {
                    if (destino != origem.Parent.Parent)
                    {
                        if (destino.Parent.Parent.Parent.Parent == origem.Parent.Parent.Parent.Parent.Parent.Parent)
                        {
                            if (destino.Parent.Parent.Parent == origem.Parent.Parent.Parent.Parent.Parent)
                            {
                                retorno = true;
                            }
                        }
                    }
                }
                else if (destino is Model.NoNaturezaOperacao)
                {
                    if (destino != origem.Parent.Parent.Parent.Parent)
                    {
                        if (destino.Parent.Parent.Parent == origem.Parent.Parent.Parent.Parent.Parent.Parent)
                        {
                            if (destino.Parent.Parent == origem.Parent.Parent.Parent.Parent.Parent)
                            {
                                retorno = true;
                            }
                        }
                    }
                }
                else if (destino is Model.NoDescarte)
                    retorno = true;
            }
            else
                retorno = false;

            return retorno;

        }

        /// <summary>
        /// Valida se a origem do movimento drag and drop é válida
        /// </summary>
        /// <param name="origem"></param>
        private bool ValidarOrigem(IHierarchicalItem origem)
        {
            if (origem is Model.NoOrdem || origem is Model.NoNegocio)
                return true;
            else
                return false;
        }

        /// <summary>
        /// Valida se o usuário possui permissão para o movimento do nó negócio
        /// </summary>
        /// <param name="origem"></param>
        /// <param name="destino"></param>
        private bool ValidarPermissaoNegocio(Model.NoNegocio origem, IHierarchicalItem destino)
        {
            return Permissoes.PermiteManutencaoNegocio;
        }

        /// <summary>
        /// Obtém um determinado cliente
        /// </summary>
        /// <param name="parameter"></param>
        private Model.Cliente ObterCliente(Model.Parameter.FiltroCliente parameter)
        {
            Model.Cliente retorno = null;
            try
            {
                retorno = _communicationCliente.ObterCliente(parameter);
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
            return retorno;
        }

        /// <summary>
        /// Obtém as informações sobre o movimento do módulo de ordens
        /// </summary>
        private Model.InformacoesMovimento ObterInformacoesMovimento()
        {
            Model.InformacoesMovimento retorno = null;
            try
            {
                retorno = _communicationControleMovimentoOrdens.ObterInformacoesMovimento(new Model.DataMovimento());
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
            return retorno;
        }

        /// <summary>
        /// Obtém as permissões do operador logado
        /// </summary>
        private void ObterPermissoes()
        {
            Permissoes.PermiteCancelar = AuthorizationManager.GetInstance().CheckUserAccess("ORD", "EORD");
            Permissoes.PermiteAlterar = AuthorizationManager.GetInstance().CheckUserAccess("ORD", "AORD");
            Permissoes.PermiteManutencaoNegocio = AuthorizationManager.GetInstance().CheckUserAccess("ORD", "MNEG");
        }

        /// <summary>
        /// Obtém um determinado título
        /// </summary>
        /// <param name="parameter"></param>
        private Model.Titulo ObterTitulo(Model.Parameter.FiltroTitulo parameter)
        {
            Model.Titulo retorno = null;

            try
            {
                retorno = _communicationTitulo.ObterTitulo(parameter);
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }

            return retorno;
        }

        /// <summary>
        /// Transfere um nó ordem para um determinado destino
        /// </summary>
        /// <param name="origem"></param>
        /// <param name="destino"></param>
        private void TransferirNo(Model.NoOrdem origem, IHierarchicalItem destino)
        {
            Model.NoSituacaoCasamento objetoSitCasamento = null;
            Model.NoDiscricionaria objetoDiscricionaria = null;


            if (destino is Model.NoNaturezaOperacao)
            {
                Model.NoTipoObjetoConsulta objetoOrdem = origem.Parent.Parent.Parent as Model.NoTipoObjetoConsulta;

                foreach (Model.NoTipoObjetoConsulta item in ((Model.NoNaturezaOperacao)destino).Children)
                {

                    if (item.TipoObjeto == Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Enum.TipoObjetoConsulta.Ordem)
                    {
                        objetoOrdem = item;
                        break;
                    }
                }

                foreach (Model.NoDiscricionaria item in objetoOrdem.Children)
                {

                    if (item.Discricionaria == origem.Discricionaria.Value)
                    {
                        objetoDiscricionaria = item;
                        break;
                    }
                }

                if (origem.QuantidadeExecutada == 0)
                {
                    foreach (Model.NoSituacaoCasamento item in objetoDiscricionaria.Children)
                    {
                        if (item.Situacao == Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Enum.SituacaoCasamento.NaoCasada)
                        {
                            objetoSitCasamento = item;
                            break;
                        }
                    }
                }
                else
                {
                    foreach (Model.NoSituacaoCasamento item in objetoDiscricionaria.Children)
                    {
                        if (item.Situacao == Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Enum.SituacaoCasamento.Casada)
                        {
                            objetoSitCasamento = item;
                            break;
                        }
                    }
                }

                origem.Parent = objetoSitCasamento;
                objetoSitCasamento.Children.Add(origem);
                origem.Parent.Children.Remove(origem);
            }
            else if (destino is Model.NoDiscricionaria)
            {
                if (origem.QuantidadeExecutada == 0)
                {
                    foreach (Model.NoSituacaoCasamento item in ((Model.NoDiscricionaria)destino).Children)
                    {
                        if (item.Situacao == Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Enum.SituacaoCasamento.NaoCasada)
                        {
                            objetoSitCasamento = item;
                            break;
                        }
                    }
                }
                else
                {
                    foreach (Model.NoSituacaoCasamento item in ((Model.NoDiscricionaria)destino).Children)
                    {
                        if (item.Situacao == Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Enum.SituacaoCasamento.Casada)
                        {
                            objetoSitCasamento = item;
                            break;
                        }
                    }
                }
                origem.Parent.Children.Remove(origem);  
                origem.Parent = objetoSitCasamento;
                objetoSitCasamento.Children.Add(origem);
                          
            }
            else if (destino is Model.NoSituacaoCasamento)
            {

                origem.Parent.Children.Remove(origem);

                if (origem.NaturezaOperacao == Model.Enum.NaturezaOperacao.Compra && ((Model.NoNaturezaOperacao)destino.Parent.Parent.Parent).Natureza == Model.Enum.NaturezaOperacao.Venda)
                {
                    origem.NaturezaOperacao = Model.Enum.NaturezaOperacao.Venda;
                }

                if (origem.NaturezaOperacao == Model.Enum.NaturezaOperacao.Venda && ((Model.NoNaturezaOperacao)destino.Parent.Parent.Parent).Natureza == Model.Enum.NaturezaOperacao.Compra)
                {
                    origem.NaturezaOperacao = Model.Enum.NaturezaOperacao.Compra;
                }

                if (origem.Discricionaria.Value && !((Model.NoDiscricionaria)destino.Parent).Discricionaria)
                {
                    origem.Discricionaria = false;
                }

                if (!origem.Discricionaria.Value && ((Model.NoDiscricionaria)destino.Parent).Discricionaria)
                {
                    origem.Discricionaria = true;
                }

                if ((origem.SituacaoCasamento == Model.Enum.SituacaoCasamento.Casada || origem.SituacaoCasamento == Model.Enum.SituacaoCasamento.ParcialmenteCasada) && (((Model.NoSituacaoCasamento)destino).Situacao == Model.Enum.SituacaoCasamento.NaoCasada))
                {
                    origem.SituacaoCasamento = Model.Enum.SituacaoCasamento.NaoCasada;
                    origem.QuantidadeExecutada = 0;
                }

                origem.Parent = (Model.NoSituacaoCasamento)destino;
                ((Model.NoSituacaoCasamento)destino).Children.Add(origem);

            }
        }

        /// <summary>
        /// Transfere um nó negócio para um determinado destino
        /// </summary>
        /// <param name="origem"></param>
        /// <param name="destino"></param>
        private void TransferirNo(Model.NoNegocio origem, IHierarchicalItem destino)
        {

            Model.NoTipoObjetoConsulta objetoNegocio = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoTipoObjetoConsulta(null, Model.Enum.TipoObjetoConsulta.Negocio);
            Model.NoSituacaoCasamento objetoSitCasamento = new Sinacor.UI.Bovespa.ManutencaoOrdens.Model.NoSituacaoCasamento(null, Model.Enum.SituacaoCasamento.Casada);

            if (destino is Model.NoNaturezaOperacao)
            {
                foreach (Model.NoTipoObjetoConsulta item in ((Model.NoNaturezaOperacao)destino).Children)
                {
                    if (item.TipoObjeto == Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Enum.TipoObjetoConsulta.Negocio)
                    {
                        objetoNegocio = item;
                        break;
                    }
                }


                if (origem.QuantidadeCasada == 0)
                {
                    foreach (Model.NoSituacaoCasamento item in objetoNegocio.Children)
                    {
                        if (item.Situacao == Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Enum.SituacaoCasamento.NaoCasada)
                        {
                            objetoSitCasamento = item;
                            break;
                        }
                    }
                }
                else
                {
                    foreach (Model.NoSituacaoCasamento item in objetoNegocio.Children)
                    {
                        if (item.Situacao == Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Enum.SituacaoCasamento.Casada)
                        {
                            objetoSitCasamento = item;
                            break;
                        }
                    }
                }

                origem.Parent = objetoSitCasamento;
                objetoSitCasamento.Children.Add(origem);
                origem.Parent.Children.Remove(origem);

            }
            else if (destino is Model.NoSituacaoCasamento)
            {
                origem.Parent.Children.Remove(origem);

                if (origem.NaturezaOperacao == Model.Enum.NaturezaOperacao.Compra && ((Model.NoNaturezaOperacao)destino.Parent.Parent).Natureza == Model.Enum.NaturezaOperacao.Venda)
                {
                    origem.NaturezaOperacao = Model.Enum.NaturezaOperacao.Venda;
                }

                if (origem.NaturezaOperacao == Model.Enum.NaturezaOperacao.Venda && ((Model.NoNaturezaOperacao)destino.Parent.Parent).Natureza == Model.Enum.NaturezaOperacao.Compra)
                {
                    origem.NaturezaOperacao = Model.Enum.NaturezaOperacao.Compra;
                }


                if ((origem.SituacaoCasamento == Model.Enum.SituacaoCasamento.Casada || origem.SituacaoCasamento == Model.Enum.SituacaoCasamento.ParcialmenteCasada) && (((Model.NoSituacaoCasamento)destino).Situacao == Model.Enum.SituacaoCasamento.NaoCasada))
                {
                    origem.SituacaoCasamento = Model.Enum.SituacaoCasamento.NaoCasada;
                    origem.QuantidadeCasada = 0;
                }

                origem.Parent = (Model.NoSituacaoCasamento)destino;
                ((Model.NoSituacaoCasamento)destino).Children.Add(origem);

            }
        }

        /// <summary>
        /// Valida se o destino do movimento drag and drop é válido
        /// </summary>
        /// <param name="destino"></param>
        private bool ValidarDestino(IHierarchicalItem destino)
        {
            if (destino is Model.NoDescarte || destino is Model.NoNaturezaOperacao || destino is Model.NoDiscricionaria || destino is Model.NoSituacaoCasamento)
                return true;
            else
                return false;

        }

        /// <summary>
        /// Consulta os negócios executados (casados) para a ordem passada como parâmetro
        /// de entrada e retorna para quem o consumiu
        /// </summary>
        /// <param name="ordem"></param>
        private ModelCollection<Model.Negocio> ConsultarNegociosExecutados(Model.ChaveOrdem ordem)
        {

            ModelCollection<Model.Negocio> retorno = null;
            try
            {
                retorno = _communicationNegocio.ConsultarNegociosExecutados(ordem);
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
            return retorno;
        }

        /// <summary>
        /// Filtra os negócios carregados na variável global _negocios, utilizando LINQ e
        /// aplicando os filtros passados como parâmetro de entrada
        /// </summary>
        /// <param name="filtro"></param>
        private ModelCollection<Model.Negocio> ConsultarNosNegocios(Model.Parameter.FiltroOrdem filtro)
        {

            ModelCollection<Model.Negocio> retorno = new ModelCollection<Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Negocio>();

            if (filtro.Casadas)
            {
                var negociosCasados = Negocios.Where(x => x.Codigo == filtro.Ativo && x.CodigoCliente == filtro.Cliente && x.NaturezaOperacao.Value == filtro.NaturezaOperacao).Select(x => x).ToList();

                negociosCasados = (from v in negociosCasados
                                   where (v.QuantidadeCasada == v.Quantidade)
                                   select v).ToList();

                foreach (var item in negociosCasados)
                {
                    retorno.Add(item as Model.Negocio);
                }

            }
            else if (filtro.NaoCasadas)
            {
                var negociosNaoCasados = Negocios.Where(x => x.Codigo == filtro.Ativo && x.CodigoCliente == 0 && x.NaturezaOperacao.Value == filtro.NaturezaOperacao).Select(x => x).ToList();

                negociosNaoCasados = (from v in negociosNaoCasados
                                      where (v.QuantidadeCasada == 0)
                                      select v).ToList();

                foreach (var item in negociosNaoCasados)
                {
                    retorno.Add(item as Model.Negocio);
                }


            }
            else if (filtro.CasadasParcialmente)
            {
                var negociosCasadosParcial = Negocios.Where(x => x.Codigo == filtro.Ativo && x.CodigoCliente == filtro.Cliente && x.NaturezaOperacao.Value == filtro.NaturezaOperacao).Select(x => x).ToList();

                negociosCasadosParcial = (from v in negociosCasadosParcial
                                          where (v.QuantidadeCasada > 0 && v.QuantidadeCasada < v.Quantidade)
                                          select v).ToList();

                foreach (var item in negociosCasadosParcial)
                {
                    retorno.Add(item as Model.Negocio);
                }

            }

            return retorno;
        }


        /// <summary>
        /// Filtra as ordens carregadas na variável global _ordens, utilizando LINQ e
        /// aplicando os filtros passados como parâmetro de entrada
        /// </summary>
        /// <param name="filtro"></param>
        private ModelCollection<Model.Ordem> ConsultarNosOrdens(Model.Parameter.FiltroOrdem filtro)
        {
            ModelCollection<Model.Ordem> retorno = new ModelCollection<Sinacor.UI.Bovespa.ManutencaoOrdens.Model.Ordem>();

            if (_ordens != null)
            {
                var ordensFiltradas = Ordens.Where(x => x.Ativo == filtro.Ativo && x.CodigoCliente == filtro.Cliente && x.NaturezaOperacao.Value == filtro.NaturezaOperacao && x.Discricionaria == filtro.Discricionaria).Select(x => x).ToList();


                if (filtro.Casadas)
                {
                    ordensFiltradas = (from v in ordensFiltradas
                                       where (v.QuantidadeExecutada == v.Quantidade)
                                       select v).ToList();
                }
                else if (filtro.NaoCasadas)
                {
                    ordensFiltradas = (from v in ordensFiltradas
                                       where (v.QuantidadeExecutada == 0)
                                       select v).ToList();
                }
                else if (filtro.CasadasParcialmente)
                {
                    ordensFiltradas = (from v in ordensFiltradas
                                       where (v.QuantidadeExecutada > 0 && v.QuantidadeExecutada < v.Quantidade)
                                       select v).ToList();
                }

                foreach (var item in ordensFiltradas)
                {
                    retorno.Add(item as Model.Ordem);
                }
            }

            return retorno;
        }

        /// <summary>
        /// Consulta ordens à partir dos filtros informados
        /// </summary>
        /// <param name="parameter"></param>
        private ModelCollection<Model.Ordem> ConsultarOrdens(Model.Parameter.FiltroOrdem parameter)
        {
            ModelCollection<Model.Ordem> retorno = null;

            try
            {
                retorno = _communicationManutencaoOrdens.ConsultarOrdens(parameter);
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
            return retorno;
        }

        /// <summary>
        /// Consulta as ordens executadas (casadas) para o negócio passado como parâmetro
        /// de entrada
        /// </summary>
        /// <param name="noNegocio"></param>
        private ModelCollection<Model.Ordem> ConsultarOrdensExecutadas(Model.NoNegocio noNegocio)
        {
            ModelCollection<Model.Ordem> retorno = null;

            try
            {
                retorno = _communicationOrdem.ConsultarOrdensNegocio(noNegocio);
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
            return retorno;
        }

        /// <summary>
        /// Atualiza o estado da ordem selecionada após os casamentos ou descasamentos
        /// ocorrerem
        /// </summary>
        public void AtualizarEstadoOrdem()
        {
            try
            {
                var ret = (from v in this._negociosExecutados
                           select v.Quantidade).Sum();

                this._ordemAtual.QuantidadeExecutada = (decimal?)ret.Value;

                if ((decimal)ret.Value == 0)
                    this._ordemAtual.Saldo = this._ordemAtual.Quantidade.Value;
                else
                    this._ordemAtual.Saldo = this._ordemAtual.Quantidade.Value - (decimal)ret.Value;

            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }

        }


        #endregion

    }

}